﻿--ESNChatDB = ESNChatDB or { NUM_SCROLL_LINES = 1, delay = 20, SAY = ChatTypeInfo["SAY"].sticky, YELL = ChatTypeInfo["YELL"].sticky, EMOTE = ChatTypeInfo["EMOTE"].sticky, PARTY = ChatTypeInfo["PARTY"].sticky, RAID = ChatTypeInfo["RAID"].sticky, RAID_LEADER = ChatTypeInfo["RAID_LEADER"].sticky, RAID_WARNING = ChatTypeInfo["RAID_WARNING"].sticky, GUILD = ChatTypeInfo["GUILD"].sticky, OFFICER = ChatTypeInfo["OFFICER"].sticky, WHISPER = ChatTypeInfo["WHISPER"].sticky, REPLY = ChatTypeInfo["REPLY"].sticky, CHANNEL = ChatTypeInfo["CHANNEL"].sticky}
ESNChatDB = ESNChatDB or { NUM_SCROLL_LINES = 1, delay = 20}

-- local
BINDING_HEADER_ESN_Chat = ("ESN_Chat");

local _G = getfenv(0)
local orig = {}
local scrolldowns = {}
local frame, handlers, running, funcs = CreateFrame("Frame"), {}, {}, {"ScrollUp", "ScrollDown", "ScrollToTop", "PageUp", "PageDown"}
frame.name = "ESN_Chat"
frame:Hide()

frame:SetScript("OnUpdate", function (frame, elapsed)
	for name,v in pairs(handlers) do
		if running[name] then
			v.elapsed = v.elapsed + elapsed
			if v.elapsed >= v.rate then
				v.func(unpack(v))
				v.elapsed = 0
			end
		end
	end
end)

local function Register(name, func, rate, ...)
	handlers[name] = {
		name = name,
		func = func,
		rate = rate or 0,
		...
	}
end

local function Start(name)
	handlers[name].elapsed = 0
	running[name] = true
	frame:Show()
end

local function Stop(name)
	running[name] = nil
	if not next(running) then frame:Hide() end
end

--Editbox
ChatFrameEditBox:SetAltArrowKeyMode(false)

--Chatsticky
--[[
if ESNChatDB.SAY then ChatTypeInfo["SAY"].sticky = 1 else ChatTypeInfo["SAY"].sticky = 0 end
if ESNChatDB.YELL then ChatTypeInfo["YELL"].sticky = 1 else ChatTypeInfo["YELL"].sticky = 0 end
if ESNChatDB.EMOTE then ChatTypeInfo["EMOTE"].sticky = 1 else ChatTypeInfo["EMOTE"].sticky = 0 end
if ESNChatDB.PARTY then ChatTypeInfo["PARTY"].sticky = 1 else ChatTypeInfo["PARTY"].sticky = 0 end
if ESNChatDB.RAID then ChatTypeInfo["RAID"].sticky = 1 else ChatTypeInfo["RAID"].sticky = 0 end
if ESNChatDB.RAID_LEADER then ChatTypeInfo["RAID_LEADER"].sticky = 1 else ChatTypeInfo["RAID_LEADER"].sticky = 0 end
if ESNChatDB.RAID_WARNING then ChatTypeInfo["RAID_WARNING"].sticky = 1 else ChatTypeInfo["RAID_WARNING"].sticky = 0 end
if ESNChatDB.GUILD then ChatTypeInfo["GUILD"].sticky = 1 else ChatTypeInfo["GUILD"].sticky = 0 end
if ESNChatDB.OFFICER then ChatTypeInfo["OFFICER"].sticky = 1 ; ChatFrame1:AddMessage("ESN_Chat GUILD :"..ESNChatDB.GUILD,0,1,0) else ChatTypeInfo["OFFICER"].sticky = 0; ChatFrame1:AddMessage("ESN_Chat GUILD : nichts",0,1,0) end
if ESNChatDB.WHISPER then ChatTypeInfo["WHISPER"].sticky = 1 else ChatTypeInfo["WHISPER"].sticky = 0 end
if ESNChatDB.REPLY then ChatTypeInfo["REPLY"].sticky = 1 else ChatTypeInfo["REPLY"].sticky = 0 end
if ESNChatDB.CHANNEL then ChatTypeInfo["CHANNEL"].sticky = 1 else ChatTypeInfo["CHANNEL"].sticky = 0 end
]]--
ChatTypeInfo["SAY"].sticky = 1
ChatTypeInfo["YELL"].sticky = 1
ChatTypeInfo["EMOTE"].sticky = 1
ChatTypeInfo["PARTY"].sticky = 1
ChatTypeInfo["RAID"].sticky = 1
ChatTypeInfo["RAID_LEADER"].sticky = 1
ChatTypeInfo["RAID_WARNING"].sticky = 1
ChatTypeInfo["GUILD"].sticky = 1
ChatTypeInfo["OFFICER"].sticky = 1
ChatTypeInfo["WHISPER"].sticky = 1
ChatTypeInfo["REPLY"].sticky = 1
ChatTypeInfo["CHANNEL"].sticky = 1

--Mousescroll
local function scroller(frame, delta)
	if delta > 0 then
		if IsShiftKeyDown() then frame:ScrollToTop()
		else 
			for i = 1, ESNChatDB.NUM_SCROLL_LINES do
				frame:ScrollUp()
			end
		end		
	elseif delta < 0 then
		if IsShiftKeyDown() then frame:ScrollToBottom()
		else 
			for i = 1, ESNChatDB.NUM_SCROLL_LINES do
				frame:ScrollDown()
			end
		end
	end
end

-- Timestamp
local function hook(frame, text, ...)	
	text = string.format("[%s] %s",date("%H:%M:%S"),text)
	orig[frame](frame, text, ...)
end

--ScrollDown
local function ResetFrame(name, frame)
	Stop(name.."DownTimeout")
	Start(name.."DownTick")
end

local function ScrollOnce(name, frame)
	if frame:AtBottom() then Stop(name.."DownTick")
	else scrolldowns[name](frame) end
end

--ChatFrames
for i=1,NUM_CHAT_WINDOWS do
	local name = "ChatFrame" .. i
	local frame = _G[name]
	scrolldowns[name] = frame.ScrollDown
	Register(name.."DownTick", ScrollOnce, 0.1, name, frame)
	Register(name.."DownTimeout", ResetFrame, ESNChatDB.delay, name, frame)
	for _,func in ipairs(funcs) do
		local orig = frame[func]
		frame[func] = function(...)
			Stop(name.."DownTick")
			Start(name.."DownTimeout", 1)
			orig(...)
		end
	end	
	frame:EnableMouseWheel(true)
	frame:SetScript("OnMouseWheel", scroller)
	orig[frame] = frame.AddMessage
	frame.AddMessage = hook
end

--[[
----------------------------------------------------------------
-- GUI
-- Some widget functions taken from OmniCC, credits to Tuller
----------------------------------------------------------------
function ESN_Chat_CreatePanel(self,name)
	local panel = CreateFrame('Frame', self:GetName()..name, self, 'OptionFrameBoxTemplate')
	panel:SetBackdropBorderColor(0.4, 0.4, 0.4)
	panel:SetBackdropColor(0.15, 0.15, 0.15, 0.5)
	getglobal(panel:GetName() .. 'Title'):SetText(name)

	return panel
end

function ESN_Chat_CreateCheckButton(name, parent)
	local button = CreateFrame('CheckButton', parent:GetName()..name, parent, 'OptionsCheckButtonTemplate')
	getglobal(button:GetName() .. 'Text'):SetText(name)

	return button
end

function ESN_Chat_CreateDisplayPanel(parent)
	local panel = ESN_Chat_CreatePanel(parent,"Sticky Options")
	panel:SetWidth(330); panel:SetHeight(320)
	
	local sayt = ESN_Chat_CreateCheckButton("Sagen-Kanal festtackern", panel)
	sayt:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["SAY"].sticky) end)
	sayt:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.SAY = 1 else ESNChatDB.SAY = 0 end; ChatTypeInfo["SAY"].sticky = ESNChatDB.SAY end)
	sayt:SetPoint('TOPLEFT', 10, -8)
	
	local yellt = ESN_Chat_CreateCheckButton("Schreien-Kanal festtackern", panel)
	yellt:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["YELL"].sticky) end)
	yellt:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.YELL = 1 else ESNChatDB.YELL = 0 end; ChatTypeInfo["YELL"].sticky = ESNChatDB.YELL end)
	yellt:SetPoint('TOP', sayt, "BOTTOM", 0, 8)
	
	local emotet = ESN_Chat_CreateCheckButton("Emote-Kanal festtackern", panel)
	emotet:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["EMOTE"].sticky) end)
	emotet:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.EMOTE = 1 else ESNChatDB.EMOTE = 0 end; ChatTypeInfo["EMOTE"].sticky = ESNChatDB.EMOTE end)
	emotet:SetPoint('TOP', yellt, "BOTTOM", 0, 8)
	
	local partyt = ESN_Chat_CreateCheckButton("Gruppen-Kanal festtackern", panel)
	partyt:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["PARTY"].sticky) end)
	partyt:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.PARTY = 1 else ESNChatDB.PARTY = 0 end; ChatTypeInfo["PARTY"].sticky = ESNChatDB.PARTY end)
	partyt:SetPoint('TOP', emotet, "BOTTOM", 0, 8)
	
	local raidt = ESN_Chat_CreateCheckButton("Schlachtzug-Kanal festtackern", panel)
	raidt:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["RAID"].sticky) end)
	raidt:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.RAID = 1 else ESNChatDB.RAID = 0 end; ChatTypeInfo["RAID"].sticky = ESNChatDB.RAID end)
	raidt:SetPoint('TOP', partyt, "BOTTOM", 0, 8)
	
	local raidlt = ESN_Chat_CreateCheckButton("Schlachtzugsleiter-Kanal festtackern", panel)
	raidlt:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["RAID_LEADER"].sticky) end)
	raidlt:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.RAID_LEADER = 1 else ESNChatDB.RAID_LEADER = 0 end; ChatTypeInfo["RAID_LEADER"].sticky = ESNChatDB.RAID_LEADER end)
	raidlt:SetPoint('TOP', raidt, "BOTTOM", 0, 8)
	
	local raidwt = ESN_Chat_CreateCheckButton("Schlachtzugswarnung-Kanal festtackern", panel)
	raidwt:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["RAID_WARNING"].sticky) end)
	raidwt:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.RAID_WARNING = 1 else ESNChatDB.RAID_WARNING = 0 end; ChatTypeInfo["RAID_WARNING"].sticky = ESNChatDB.RAID_WARNING end)
	raidwt:SetPoint('TOP', raidlt, "BOTTOM", 0, 8)
	
	local guildt = ESN_Chat_CreateCheckButton("Gilden-Kanal festtackern", panel)
	guildt:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["GUILD"].sticky) end)
	guildt:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.GUILD = 1 else ESNChatDB.GUILD = 0 end; ChatTypeInfo["GUILD"].sticky = ESNChatDB.GUILD end)
	guildt:SetPoint('TOP', raidwt, "BOTTOM", 0, 8)
	
	local officert = ESN_Chat_CreateCheckButton("Offiziers-Kanal festtackern", panel)
	officert:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["OFFICER"].sticky) end)
	officert:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.OFFICER = 1 else ESNChatDB.OFFICER = 0 end; ChatTypeInfo["OFFICER"].sticky = ESNChatDB.OFFICER end)
	officert:SetPoint('TOP', guildt, "BOTTOM", 0, 8)
	
	local whispert = ESN_Chat_CreateCheckButton("Flüster-Kanal festtackern", panel)
	whispert:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["WHISPER"].sticky) end)
	whispert:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.WHISPER = 1 else ESNChatDB.WHISPER = 0 end; ChatTypeInfo["WHISPER"].sticky = ESNChatDB.WHISPER end)
	whispert:SetPoint('TOP', officert, "BOTTOM", 0, 8)
	
	local replyt = ESN_Chat_CreateCheckButton("Zurückflüster-Kanal festtackern", panel)
	replyt:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["REPLY"].sticky) end)
	replyt:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.REPLY = 1 else ESNChatDB.REPLY = 0 end; ChatTypeInfo["REPLY"].sticky = ESNChatDB.REPLY end)
	replyt:SetPoint('TOP', whispert, "BOTTOM", 0, 8)
	
	local channelt = ESN_Chat_CreateCheckButton("Chat-Kanäle festtackern", panel)
	channelt:SetScript('OnShow', function(self) self:SetChecked(ChatTypeInfo["CHANNEL"].sticky) end)
	channelt:SetScript('OnClick', function(self) if self:GetChecked() then ESNChatDB.CHANNEL = 1 else ESNChatDB.CHANNEL = 0 end; ChatTypeInfo["CHANNEL"].sticky = ESNChatDB.CHANNEL end)
	channelt:SetPoint('TOP', replyt, "BOTTOM", 0, 8)
	
	return panel
end

function ESN_Chat_AddPanelOptions()
	local panel = CreateFrame("Frame","ESN_Chat_OptionsFrame",UIParent)
	panel.name = "ESN_Chat"
	
	local display = ESN_Chat_CreateDisplayPanel(panel)
	display:SetPoint('TOPLEFT',10,-24)
	
	InterfaceOptions_AddCategory(panel)
end

ESN_Chat_AddPanelOptions()
]]--